
#include "cmdselectdatafromdbsvr.h"
#include "../mainctrl.h"

char CCmdSelectDataFromDBSvr::szBuf[CTMsgHead::EMAX_MSGLEN];

CT_REGISTER_ASYNCCMD(ID_MAINDB_SELECTDATA , CCmdSelectDataFromDBSvr);

CCmdSelectDataFromDBSvr::CCmdSelectDataFromDBSvr()
{
}

CCmdSelectDataFromDBSvr::~CCmdSelectDataFromDBSvr()
{

}

int CCmdSelectDataFromDBSvr::Do(void* pData)
{
    int iRet = 0;

    if(pstMainCtrl == NULL )
    {
        CT_WARNING((""));
        return Done(RET_SYSTEM_FAIL);
    }

    if (stReq.m_ucCheckUpdateMgr != 0)
    {
        CVarObjectHead stVarObjectHead;
        iRet = CMainCtrl::GetDataFromUpdateMgr(stReq.m_stKey, szBuf, sizeof(szBuf), stVarObjectHead);
        if (iRet == 0) //找到数据
        {
            iRet = StoreData(szBuf, stVarObjectHead.m_iDataLen);
            return Done(iRet);
        }
    }

    //数据没有找到,向dbsvr发出请求
    CTMsgHead stMsgHead;
    stMsgHead.shMsgID = ID_MAINDB_SELECTDATA ;
    stMsgHead.shMsgType = EMT_REQUEST;
    stMsgHead.iCmdSeq = GetCmdSeq();
    stMsgHead.llMsgAct = reinterpret_cast<int64>(this);

    CTBuffer& stBuf = pstMainCtrl->m_stEncodeBuf;
    CTCodeStream s(stBuf);

    CodeConvert(s, stMsgHead, NULL, bin_encode());
    CodeConvert(s, stReq, NULL, bin_encode());
    if (s.m_iRet)
    {
        CT_WARNING(("Fail to encode request, ret = %d, type %d, str_id %s, int_id %ld", s.m_iRet,
                stReq.m_stKey.m_chDataType, stReq.m_stKey.m_sStrID(), stReq.m_stKey.m_u64ID));
        return Done(RET_SYSTEM_FAIL);
    }

    CT_TRACE(("select data from dbsvr type %d, str_id %s, int_id %ld",
         stReq.m_stKey.m_chDataType, stReq.m_stKey.m_sStrID(), stReq.m_stKey.m_u64ID));
    iRet = CMainCtrl::m_pstMain->RequestToDB(s.m_pszBuf, s.m_ushPos);
    if (iRet)
    {
        CT_WARNING(("Fail to send request to server, ret = %d", iRet));
        return Done(RET_SYSTEM_FAIL);
    }

    return RET_OK;
}

int CCmdSelectDataFromDBSvr::OnAnswer(void * pData)
{
    int iRet = 0;

    if (NULL == pData)
    {
        CT_ERROR(("NULL input pointer"));
        return Done(RET_INVALID_PARAM);
    }

    CCmdOnAnswerParam* pstParam = (CCmdOnAnswerParam*) pData;
    if((CMainCtrl*)(pstParam->m_pMain) != pstMainCtrl ||
        pstParam->m_pstMsgHead->shMsgID != ID_MAINDB_SELECTDATA ||
        pstParam->m_pstMsgHead->shMsgType != EMT_ANSWER)
    {
        return Done(RET_SYSTEM_FAIL);
    }

    if (stReq.m_ucCheckUpdateMgr != 0)
    {
        CVarObjectHead stVarObjectHead;
        iRet = CMainCtrl::GetDataFromUpdateMgr(stReq.m_stKey, szBuf, sizeof(szBuf), stVarObjectHead);
        if (iRet == 0) //找到数据
        {
            iRet = StoreData(szBuf, stVarObjectHead.m_iDataLen);
            return Done(iRet);
        }
    }

    //解包
    iRet = CodeConvert(*pstParam->m_pstCode, stAns, NULL, bin_decode());
    if (iRet != 0)
    {
        CT_WARNING(("decode ans error"));
        return Done(iRet);
    }

    stAns.pszData = pstParam->m_pstCode->m_pszBuf + pstParam->m_pstCode->m_ushPos;

    //副本详细信息特殊处理
    if (DT_INSTANCE_ZONE_DETAIL_INFO == stReq.m_stKey.m_chDataType)
    {
        if (RET_NO_RECORDER == stAns.stResult.iResultID)
        {
            CInstanceZoneDetailInfo stInstanceZoneDetailInfo;
            stInstanceZoneDetailInfo.InitByKey((int)stReq.m_stKey.m_u64ID);

            int iIndex = pstMainCtrl->m_stInstanceZoneDetailInfoHash.HashAlloc(stInstanceZoneDetailInfo.GetKey());
            if (iIndex >= 0)
            {
                pstMainCtrl->m_stInstanceZoneDetailInfoHash[iIndex] = stInstanceZoneDetailInfo;
                stAns.stResult.iResultID = RET_OK;
            }
        }
    }

    if (stAns.stResult.iResultID != RET_OK)
    {
        CT_WARNING(("select data from dbsvr result %d, type %d, str_id %s, int_id %ld",
            stAns.stResult.iResultID, stReq.m_stKey.m_chDataType, stReq.m_stKey.m_sStrID(), stReq.m_stKey.m_u64ID));
        return Done(stAns.stResult.iResultID);
    }

    iRet = StoreData(stAns.pszData, stAns.iDataLen);
    return Done(iRet);
}

int CCmdSelectDataFromDBSvr::StoreData(char* szDataBuf, int iDataLen)
{
    int iRet = 0;

    if (szDataBuf == NULL)
    {
        return RET_SYSTEM_FAIL;
    }

    if (iDataLen <= 0)
    {
        return RET_OK;
    }

    switch(stReq.m_stKey.m_chDataType)
    {
    case DT_PLAYER_BASE_INFO:
        {
            CPlayerBaseInfo stPlayerBaseInfo;
            iRet = pstMainCtrl->DataDecode(stPlayerBaseInfo, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);
            int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashAlloc(stPlayerBaseInfo._uiGID);
            if (iIndex >= 0)
            {
                pstMainCtrl->m_stEquipMgr.UpdatePotenLevel (stPlayerBaseInfo);
                pstMainCtrl->m_stPlayerBaseInfoHash[iIndex] = stPlayerBaseInfo;
            }
        }
        break;
    case DT_PLAYER_GID:
        {
            CTSizeString<USER_TOKEN_LEN> szUserToken;
            szUserToken.Set("%s", stReq.m_stKey.m_sStrID());
            
            CGidList stGidList;
            iRet = pstMainCtrl->DataDecode(stGidList, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);
            int iIndex = pstMainCtrl->m_stUserTokenToGID.HashAlloc(szUserToken);
            if (iIndex >= 0)
            {
#ifdef _DEBUG
                CT_TRACE(("DT_PLAYER_GID: token %s; count %d", szUserToken(), stGidList._auiGID.Size()));
                for (int i = 0; i < stGidList._auiGID.Size(); ++i)
                {
                    CT_TRACE(("DT_PLAYER_GID: gid %u", stGidList._auiGID[i]));
                }
#endif
                
                pstMainCtrl->m_stUserTokenToGID[iIndex] = stGidList;
            }
            else
            {
                CT_ERROR(("alloc from m_stUserTokenToGID error"));
            }
        }
        break;
    case DT_MAX_PLAYER_GID:
        {
            int64 i64MaxGID = 0;        //由于使用了sql 的max 函数，返回值类型有变化
            iRet = pstMainCtrl->DataDecode(i64MaxGID, szDataBuf, iDataLen);
            pstMainCtrl->m_uiMaxGID = i64MaxGID % MAX_USER_PER_ZONE;
        }
        break;
    case DT_PLAYER_DETAIL_INFO:
        {
            CPlayerDetailInfo stPlayerDetailInfo;
            iRet = pstMainCtrl->DataDecode(stPlayerDetailInfo, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);
            int iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashAlloc(stPlayerDetailInfo._uiGID);
            if (iIndex >= 0)
            {
                stPlayerDetailInfo._stUserClan.UpdateJoinClanCount ();
                pstMainCtrl->m_stPlayerDetailInfoHash[iIndex] = stPlayerDetailInfo;
            }
        }
        break;
    case DT_PLAYER_DETAIL_EX1_INFO:
        {
            CPlayerDetailInfoEx1 stPlayerDetailInfoEx1;
            iRet = pstMainCtrl->DataDecode(stPlayerDetailInfoEx1, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);

            stPlayerDetailInfoEx1._uiGID = CT_UINT64_LOW(stReq.m_stKey.m_u64ID);
            int iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashAlloc(stPlayerDetailInfoEx1._uiGID);
            if (iIndex >= 0)
            {
                pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex] = stPlayerDetailInfoEx1;
            }
        }
        break;
    case DT_PLAYER_SNS_DETAIL_INFO:
        {
            CPlayerSnsDetailInfo stPlayerSnsDetailInfo;
            iRet = pstMainCtrl->DataDecode(stPlayerSnsDetailInfo, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);
            int iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashAlloc(stPlayerSnsDetailInfo._uiGID);
            if (iIndex >= 0)
            {
                pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex] = stPlayerSnsDetailInfo;
            }
        }
        break;
    case DT_PLAYER_SNS_COMM_INFO:
        {
            CPlayerSnsCommInfo stPlayerSnsCommInfo;
            iRet = pstMainCtrl->DataDecode(stPlayerSnsCommInfo, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);
            int iIndex = pstMainCtrl->m_stPlayerSnsCommInfoHash.HashAlloc(stPlayerSnsCommInfo._uiGID);
            if (iIndex >= 0)
            {
                pstMainCtrl->m_stPlayerSnsCommInfoHash[iIndex] = stPlayerSnsCommInfo;
                pstMainCtrl->m_auiAllRegisterGID.AddOneItem(stPlayerSnsCommInfo._uiGID);
            }

            //初始化user token
            iIndex = pstMainCtrl->m_stUserTokenToGID.HashAlloc(stPlayerSnsCommInfo._sUserToken);
            if (iIndex >= 0)
            {
                pstMainCtrl->m_stUserTokenToGID[iIndex]._auiGID.AddOneItem(stPlayerSnsCommInfo._uiGID);
            }
        }
        break;
    case DT_PLAYER_SNS_COMM_INFO_COUNT:
        {
            //由父命令处理
        }
        break;
    case DT_PLAYER_UNACT_PARTNER:
        {
            CUnactPartnerInfo stUnactPartnerInfo;
            iRet = pstMainCtrl->DataDecode(stUnactPartnerInfo, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);
            int iIndex = pstMainCtrl->m_stUnactPartnerInfoHash.HashAlloc(stUnactPartnerInfo._uiGID);
            if (iIndex >= 0)
            {
                pstMainCtrl->m_stUnactPartnerInfoHash[iIndex] = stUnactPartnerInfo;
            }
        }
        break;
    case DT_ARENA_RANK_COUNT:
        {
            //由父命令处理
        }
        break;
    case DT_ARENA_RANK:
        {
            CArenaRank stArenaRank;
            iRet = pstMainCtrl->DataDecode(stArenaRank, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);
            iRet = pstMainCtrl->m_stArenaMgr.AddData(stArenaRank);
            CHECK_RETURN(iRet);
        }
        break;
    case DT_ZONE_COUNT:
        {
            //由父命令处理
        }
        break;
    case DT_ZONE_DATA:
        {
            CZoneData stZoneData;
            iRet = pstMainCtrl->DataDecode(stZoneData, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);

            pstMainCtrl->m_stZoneOnlineData.SetZoneData(stZoneData);
        }
        break;
    case DT_CLAN_DATA_COUNT:
        {
            //由父命令处理
        }
        break;
    case DT_CLAN_DATA:
        {
            CClanData stClanData;
            iRet = pstMainCtrl->DataDecode(stClanData, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);

            int iIndex = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashAlloc(stClanData._uiClanID) ;
            if (iIndex < 0)
            {
                return ERROR_ZONE_CLAN_NUM_FULL;
            }

            //学院合并，修改家族信息
            bool bChangeAca = false;
            if (ACADEMY_TYPE_RAVAN == stClanData._ucAcademyType)
            {
                stClanData._ucAcademyType = ACADEMY_TYPE_SLEN;
                bChangeAca = true;
            }
            else if (ACADEMY_TYPE_HUFF == stClanData._ucAcademyType)
            {
                stClanData._ucAcademyType = ACADEMY_TYPE_GRAN;
                bChangeAca = true;
            }

            if (bChangeAca)
            {
                //保存数据
                CVarObjectKey stKey;
                stKey.m_chDataType = DT_CLAN_DATA;
                stKey.m_u64ID = stClanData._uiClanID;
                CMainCtrl::m_pstMain->UpdateData(stKey, stClanData, VOP_UPDATE);
            }
            //学院合并 end

            iRet = pstMainCtrl->m_stClanMgr.InitClanData(pstMainCtrl->m_stClanMgr._stClanEntryHash[iIndex], stClanData);
            CHECK_RETURN(iRet);
        }
        break;
    case DT_INSTANCE_ZONE_DETAIL_INFO:
        {
            CInstanceZoneDetailInfo stInstanceZoneDetailInfo;
            iRet = pstMainCtrl->DataDecode(stInstanceZoneDetailInfo, szDataBuf, iDataLen);
            CHECK_RETURN(iRet);

            int iIndex = pstMainCtrl->m_stInstanceZoneDetailInfoHash.HashAlloc(stInstanceZoneDetailInfo.GetKey());
            if (iIndex >= 0)
            { 
                pstMainCtrl->m_stInstanceZoneDetailInfoHash[iIndex] = stInstanceZoneDetailInfo;
            }
        }
        break;
    default:
        break;
    }

    return 0;
}

